<?php

namespace App\Http\Controllers;

use App\Datas\Opus;
use App\Datas\User;
use App\Datas\Pay;
use App\Datas\OpusDrawing;
use App\Datas\DrawingStyle;
use App\Datas\DrawingBoardPrepare;
use App\Datas\UserDrawing;
use App\Tools\Oss;
use App\Tools\Shumei;
use App\Tools\Translator;
use App\Tools\Qq;
use App\Tools\Sensitive;
use App\Tools\FunTool;
use App\Tools\MuseFrame;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Redis;

class OpusController extends Controller {

	protected $dataUser;
	protected $dataOpus;
	protected $dataUserDrawing;
	protected $dataOpusDrawing;
	protected $dataPay;
	protected $dataMuseFrameLib;

	/**
	 * Create a new controller instance.
	 *
	 * @return void
	 */
	public function __construct() {
		$this->dataUser = new User();
		$this->dataOpus = new Opus();
		$this->dataUserDrawing = new UserDrawing();
		$this->dataOpusDrawing = new OpusDrawing();
		$this->dataPay = new Pay();
		$this->dataMuseFrameLib = new MuseFrame();
	}


	public function testPrint(Request $request) {
		for($i = 0; $i < 100; $i++) {
			$ps = [
				'cover of a astronaut by ilya kuvshinov, cloudy sky background lush landscape ln illustration concept art anime key visual trending pixiv by victo ngai fanbox by greg rutkowski makoto shinkai takashi takeuchi studio ghibli',
				'organic cyborg, holographic material, diffuse lighting, fantasy, intricate, elegant, highly detailed, lifelike, photorealistic, digital painting, artstation, illustration, smooth, sharp focus, art by john collier and albert aublet and krenz cushart and artem demura and alphonse mucha',
				'A highly detailed matte painting of a japanese urban residential street and park with a bright shimmering sky by Studio Ghibli, Mokoto Shinkai, by Artgerm, by beeple, volumetric lighting, octane render, 4K resolution, trending on artstation, vivid colours',
				"a scary lonely witch's hut in the forest a lot of crows circling from above the view at the foot rule of thirds golden ratio, fake detail, trending pixiv fanbox, acrylic palette knife, style of makoto shinkai studio ghibli genshin impact james gilleard greg rutkowski chiho aoshima",
				'Intricate stunning highly detailed raven by agostino arrivabene and Vladimir Kush, surreal sculpture, ultra realistic, Horror, dramatic lighting, full moon, blood moon, thick black swirling particle smoke tornado, fire embers, trending on artstation'
			];
			foreach($ps as $prompt) {


				//$prompt = $request->post('prompt');
				$taskId = $this->getRoundToken();
				$data = $this->dataOpus->addPrint($prompt, $prompt, $taskId, 0);
			}
		}

		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 通用画作接口
	 */
	public function print(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'],
		]);
		$prompt = $request->post('prompt');
		$taskId = $this->getRoundToken();

		$userId = $this->getTokenUser() ?? 0;
		$curUser = $this->dataUser->getUser($userId);

		$lanage = $this->getLanage();
		if($lanage == 'zh') {
			$noVipArr = [
				'照片画板：韩风穿着，可爱的20岁美女', '照片画板：健壮的肌肉帅哥，下雨湿身', '照片画板：巴西模特，维多利亚的秘密超模', '二次元画板：穿着性感短裙的少女，在花园里',
				'照片画板：未来风格的机甲猛男，背景是被毁灭的城市'
			];
		} else {
			$noVipArr = [
				'Photo board: Han Feng is wearing a lovely 20-year-old beauty',
				'Photo board: muscular handsome guy, wet in the rain',
				"Photo board: Brazilian model, Victoria's secret supermodel",
				'Anime drawing board: girls in sexy skirts, in the garden',
				'Photo board: futuristic machinist male, with a destroyed city in the background'
			];
		}


		if(!in_array($prompt, $noVipArr) && $curUser['vip_surplus'] == 0) {
			return $this->buildReturn(Code::NOT_VIP);
		}

		if($curUser['vip_surplus'] == 0) {
			if($this->dataOpus->getCount($userId) >= 5) {
				return $this->buildReturn(Code::NOT_VIP);
			}
			$this->dataOpus->incCount($userId);
		}

		if(in_array($prompt, $noVipArr)) {
			$data = $this->dataOpus->addPrintNoVip($prompt, $taskId, $userId);
			return $this->buildReturn(Code::SUCCESS, $data);
		}

		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}

		// $shumei = new Shumei();
		// $prompt = $shumei->check($prompt);

		$tPrompt = $this->dataOpus->getCacheTranslator($prompt);
		$tPrompt = $tPrompt ?? ((new Translator())->azure($this->handleSensitiveWord($prompt)));
		$tPrompt = $this->handleSensitiveWord($tPrompt);
		$this->dataOpus->setCacheTranslator($prompt, $tPrompt);

		$data = $this->dataOpus->addPrint($prompt, $tPrompt, $taskId, $userId);
		return $this->buildReturn(Code::SUCCESS, $data);

	}

	/**
	 * 免费生成画作
	 */
	public function freePrint(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'],
		]);
		$prompt = $request->post('prompt');
		$taskId = $this->getRoundToken();
		$deviceId = $this->getDeviceId();
		if(!$deviceId) {
			return $this->buildReturn(Code::ERROR);
		}

		$lanage = $this->getLanage();
		if($lanage == 'zh') {
			$noVipArr = [
				'经典画板：太空魅魔，在空间站睡着，穿着透明的紧身衣', 'MidJourney画板：精致的鸟形花纹艺术品', '照片画板：身材绝佳的维密天使，穿着金色内衣', '二次元画板：骑着扫帚的飞天小魔女，性感',
				'幻想画板：穿着华丽花纹服装的女盗贼，站在宫殿前'
			];
		} else {
			$noVipArr = [
				'Classic drawing board: Space Phantom, asleep on the space station, wearing a transparent leotard',
				'MidJourney drawing board: exquisite bird-shaped floral artwork',
				"Photo drawing board: very fit Victoria's Secret model in gold lingerie",
				'ACG drawing board: flying little magician on a broomstick, sexy',
				'Fantasy drawing board: female thief in a gorgeous floral print costume, standing in front of the palace'
			];
		}

		if(in_array($prompt, $noVipArr)) {
			//校验该设备的免费次数
			$freeNum = $this->dataOpus->getFreeNum($deviceId);
			if($freeNum >= 2) {
				return $this->buildReturn(Code::NOT_VIP);
			}
			$promptKey = array_search($prompt, $noVipArr);
			$userId = $this->getTokenUser() ?? 0;
			$data = $this->dataOpus->addPrintNoVip($prompt, $taskId, $userId, $deviceId, $promptKey, true);

			return $this->buildReturn(Code::SUCCESS, $data);
		}

		return $this->buildReturn(Code::SUCCESS);
	}

	public function getFreeNum(Request $request) {
		$deviceId = $this->getDeviceId();
		if(!$deviceId) {
			return $this->buildReturn(Code::ERROR);
		}

		$freeNum = $this->dataOpus->getFreeNum($deviceId);
		return $this->buildReturn(Code::SUCCESS, ['free_num' => 2 - $freeNum, 'free_id' => 1]);
	}

	/**
	 * 获取二次元样例
	 */
	public function getAnimeExample(Request $request) {

		$lanage = $this->getLanage();
		$data = $this->dataOpus->getAnimeExample(10, $lanage);
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	public function getDrawingBoardPrepare(Request $request){

		$lanage = $request->post('lange', $this->getLanage());

		$deviceId = $this->getDeviceId() ?? '';

		$userId = $this->getTokenUser() ?? '';

		$data = DrawingBoardPrepare::getDrawingBoardPrepare($lanage, $deviceId, $userId);

		return $this->buildReturn(Code::SUCCESS, $data);

	}


	/**
	 * 获取图片列表
	 */
	public function getAnimeImages(Request $request) {
		$data = [
			'https://overseas-files.dalleai.art/anime/05.webp', 'https://overseas-files.dalleai.art/anime/02.webp',
			'https://overseas-files.dalleai.art/anime/03.webp', 'https://overseas-files.dalleai.art/anime/04.webp',
			'https://overseas-files.dalleai.art/anime/01.webp', 'https://overseas-files.dalleai.art/anime/06.webp',
		];
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 二次元作画
	 */
	public function printAnime(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'], //'negative_prompt' => ['required'],
			'resolution' => ['required', Rule::in([1, 2, 3])]
		]);

		$prompt = $request->post('prompt');
		$negativePrompt = '';
		$resolution = $request->post('resolution');


		//竖图
		if($resolution == 1) {
			$width = 512;
			$height = 768;
		}
		//正方形
		if($resolution == 2) {
			$width = 768;
			$height = 768;
		}
		//横图
		if($resolution == 3) {
			$width = 768;
			$height = 512;
		}

		$taskId = $this->getRoundToken();
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$curUser = $this->dataUser->getUser($userId);
		if($curUser['ecy_vip_surplus'] == 0) {
			return $this->buildReturn(Code::NOT_ECY_VIP);
		}

		if(!$this->dataOpus->getPaintCountOfDay($userId)) {
			return $this->buildReturn(Code::NOT_PAINT_NUM);
		}

		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}

		$tPrompt = $this->dataOpus->getCacheTranslator($prompt);
		
		$tPrompt = $tPrompt ?? ((new Translator())->azure($this->handleSensitiveWord($prompt)));
		
		$this->dataOpus->setCacheTranslator($prompt, $tPrompt);
		$tPrompt = $this->handleSensitiveWord($tPrompt);
		

		//增加一次用户每日作画次数
		// $this->dataOpus->setPaintCountOfDay($userId);

		$tPrompt = '((masterpiece)),(((best quality))),((ultra-detailed)),((illustration)), ((highres)), ((an extremely delicate and beautiful)),'.$tPrompt;
		$tnegativePrompt = 'multiple breasts, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark,text font ui, username, blurry, bad feet, single color, ((((ugly)))), (((duplicate))), ((morbid)), ((mutilated)), (((tranny))), (((trans))), (((trannsexual))), (hermaphrodite), (out of frame), extra fingers, mutated hands, ((poorly drawn hands)), ((poorly drawn face)), (((mutation))), (((deformed))), ((ugly)), blurry, ((bad anatomy)), (((bad proportions))), ((extra limbs)), (((disfigured))), out of frame, (bad anatomy), gross proportions, (malformed limbs), ((missing arms)), ((missing legs)), (((extra arms))), (((extra legs))), mutated hands,(fused fingers), (too many fingers), (((long neck)))';
		$data = $this->dataOpus->addPrint($prompt, $tPrompt, $taskId, $userId, '', 2, $negativePrompt, $tnegativePrompt, $height, $width);
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 其他的画板作画
	 */
	public function otherPrint(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'], //'negative_prompt' => ['required'],
			'resolution' => ['required', Rule::in([1, 2, 3])], 'drawing_id' => ['required'],
			// 'fmt_prompt' => ['required'],
		]);

		$prompt = $request->post('prompt');
		$resolution = $request->post('resolution');
		$drawingId = $request->post('drawing_id');
		$fmtPrompt = $request->post('fmt_prompt') ? $request->post('fmt_prompt') : "multiple breasts, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark,text font ui, username, blurry, bad feet, single color, ((((ugly)))), (((duplicate))), ((morbid)), ((mutilated)), (((tranny))), (((trans))), (((trannsexual))), (hermaphrodite), (out of frame), extra fingers, mutated hands, ((poorly drawn hands)), ((poorly drawn face)), (((mutation))), (((deformed))), ((ugly)), blurry, ((bad anatomy)), (((bad proportions))), ((extra limbs)), (((disfigured))), out of frame, (bad anatomy), gross proportions, (malformed limbs), ((missing arms)), ((missing legs)), (((extra arms))), (((extra legs))), mutated hands,(fused fingers), (too many fingers), (((long neck)))";
		//$negativePrompt = $request->post('negative_prompt');
		$negativePrompt = '';

		//竖图
		if($resolution == 1) {
			$width = 512;
			$height = 768;
		}
		//正方形
		if($resolution == 2) {
			$width = 768;
			$height = 768;
		}
		//横图
		if($resolution == 3) {
			$width = 768;
			$height = 512;
		}

		$taskId = $this->getRoundToken();
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$curUser = $this->dataUser->getUser($userId);

		$version = $this->getVersion();
		if(version_compare($version, '1.5.0') >= 0) {
			if($curUser['vip_exp'] < time() && $curUser["is_super_vip"] == 0) {
				return $this->buildReturn(Code::NOT_DRAWING);
			}
		} else {
			$isEffective = $this->dataUserDrawing->getUserDrawIsEffective($userId, $drawingId);
			//不是永久会员，也没有单独购买画板
			if($curUser['vip_exp'] < time() && !$isEffective) {
				return $this->buildReturn(Code::NOT_DRAWING);
			}
		}

		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}

		$tPrompt = $this->dataOpus->getCacheTranslator($prompt);
		
		$tPrompt = $tPrompt ?? ((new Translator())->azure($this->handleSensitiveWord($prompt)));
		
		$this->dataOpus->setCacheTranslator($prompt, $tPrompt);
		$tPrompt = $this->handleSensitiveWord($tPrompt);
		

		//增加一次用户每日作画次数
		// $this->dataOpus->setPaintCountOfDay($userId);


		if($drawingId == 4) {
			$defaultTprompt = " (high detailed skin:1.2), 8k uhd, dslr, soft lighting, high quality, film grain, Fujifilm XT3";
		} else if($drawingId == 6) {
			$defaultTprompt = "beautiful(insanely detailed:1.5), light particle, (highest quality, Alessandro Casagrande, Greg Rutkowski, Sally Mann, concept art, 4k), (colorful), (high sharpness), ((detailed pupils))((painting:1.1)), (digital painting:1.1), detailed face and eyes,Masterpiece, best quality, highly detailed photo:1, 8k, detailed face,photorealistic,By jeremy mann, by sandra chevrier, by maciej kuciara, sharp, ((perfect body)), realistic, real shadow, 3d, ((full body)), ((dark and gloomy church background:1.2)), (by Michelangelo)";
		} else {
			$defaultTprompt = "";
		}

		$tPrompt = $tPrompt.','.$defaultTprompt;
		
		$data = $this->dataOpus->addPrint($prompt, $tPrompt, $taskId, $userId, '', 1, $negativePrompt, $fmtPrompt, $height, $width, 0, $drawingId);
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 新版二次元作画
	 */
	public function printAnimeNew(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'], 'drawing_id' => ['required'], //'negative_prompt' => ['required'],
			'resolution' => ['required', Rule::in([1, 2, 3])]
		]);

		$prompt = $request->post('prompt');
		//$negativePrompt = $request->post('negative_prompt');
		$drawingId = $request->post('drawing_id');
		$negativePrompt = '';
		$resolution = $request->post('resolution');

		$fmtPrompt = $request->post('fmt_prompt') ? $request->post('fmt_prompt') : "multiple breasts, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark,text font ui, username, blurry, bad feet, single color, ((((ugly)))), (((duplicate))), ((morbid)), ((mutilated)), (((tranny))), (((trans))), (((trannsexual))), (hermaphrodite), (out of frame), extra fingers, mutated hands, ((poorly drawn hands)), ((poorly drawn face)), (((mutation))), (((deformed))), ((ugly)), blurry, ((bad anatomy)), (((bad proportions))), ((extra limbs)), (((disfigured))), out of frame, (bad anatomy), gross proportions, (malformed limbs), ((missing arms)), ((missing legs)), (((extra arms))), (((extra legs))), mutated hands,(fused fingers), (too many fingers), (((long neck)))";

		//竖图
		if($resolution == 1) {
			$width = 512;
			$height = 768;
		}
		//正方形
		if($resolution == 2) {
			$width = 768;
			$height = 768;
		}
		//横图
		if($resolution == 3) {
			$width = 768;
			$height = 512;
		}


		$taskId = $this->getRoundToken();
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$curUser = $this->dataUser->getUser($userId);
		//Log::info("printAnimeNew2");
		$version = $this->getVersion();


		if($curUser['vip_exp'] < time() && $curUser["is_super_vip"] == 0) {
			return $this->buildReturn(Code::NOT_DRAWING);
		}


		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}

		$tPrompt = $this->dataOpus->getCacheTranslator($prompt);
		//$tnegativePrompt = $this->dataOpus->getCacheTranslator($negativePrompt);
		$tPrompt = $tPrompt ?? ((new Translator())->azure($this->handleSensitiveWord($prompt)));
		//$tnegativePrompt = $tnegativePrompt ?? ((new Translator())->youdao($negativePrompt));
		$this->dataOpus->setCacheTranslator($prompt, $tPrompt);
		$tPrompt = $this->handleSensitiveWord($tPrompt);
		//$this->dataOpus->setCacheTranslator($negativePrompt, $tnegativePrompt);

		//增加一次用户每日作画次数
		// $this->dataOpus->setPaintCountOfDay($userId);

		$tPrompt = $tPrompt.",(masterpiece, best quality, extremely detailed CG, beautiful detailed eyes, ultra-detailed, intricate details:1.2), 8k wallpaper, elaborate features, (realistic textures:0.8), highres, (vibrant colors, dynamic lighting:1.0), (high contrast:0.8)";
		$tnegativePrompt = 'watermark, text, error, nsfw, breast, pussy, blurry, jpeg artifacts, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, artist name, (worst quality, low quality:1.4), ((bad anatomy)), watermark, signature, text, logo,contact, ((extra limbs)),(3d), Six fingers,Low quality fingers';

		$data = $this->dataOpus->addPrint($prompt, $tPrompt, $taskId, $userId, '', 2, $negativePrompt, $tnegativePrompt, $height, $width, 0, $drawingId);

		return $this->buildReturn(Code::SUCCESS, $data);
	}

	public function printAnimePhoto(Request $request) {
		$this->validate($request, [
			'drawing_image' => ['required'], 'drawing_id' => ['required'],
		]);

		$drawingImage = $request->post('drawing_image');
		$drawingId = $request->post('drawing_id');
		$negativePrompt = '';

		$taskId = $this->getRoundToken();
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$curUser = $this->dataUser->getUser($userId);

		$version = $this->getVersion();
		if(version_compare($version, '1.5.0') >= 0) {
			if($curUser['vip_exp'] < time() && $curUser["is_super_vip"] == 0) {
				return $this->buildReturn(Code::NOT_DRAWING);
			}
		} else {
			$isEffective = $this->dataUserDrawing->getUserDrawIsEffective($userId, $drawingId);
			//不是永久会员，也没有单独购买画板
			if($curUser['vip_exp'] < time() && !$isEffective) {
				return $this->buildReturn(Code::NOT_DRAWING);
			}
		}

		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}

		$tPrompt = "";

		$tPrompt = $tPrompt.",(masterpiece, best quality, extremely detailed CG, beautiful detailed eyes, ultra-detailed, intricate details:1.2), 8k wallpaper, elaborate features, (realistic textures:0.8), highres, (vibrant colors, dynamic lighting:1.0), (high contrast:0.8)";
		$tnegativePrompt = 'watermark, text, error, nsfw, breast, pussy, blurry, jpeg artifacts, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, artist name, (worst quality, low quality:1.4), ((bad anatomy)), watermark, signature, text, logo,contact, ((extra limbs)),(3d), Six fingers,Low quality fingers';
		$data = $this->dataOpus->addPrint("", $tPrompt, $taskId, $userId, '', 3, $negativePrompt, $tnegativePrompt, 768, 512, 0, $drawingId, $drawingImage);
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 获取画板风格
	 */
	public function getDrawStyle(Request $request) {
		$this->validate($request, [
			'drawing_id' => ['required'],
		]);

		$drawingId = $request->get('drawing_id');

		$lanage = $this->getLanage();

		$drawingStyle = new DrawingStyle();
		$data = $drawingStyle->getList($drawingId, $lanage);

		array_unshift($data, [
			'id' => 0, "name" => "Non", "drawing_id" => 0,
			"image" => "https://overseas-files.dalleai.art/changsha/style/no.png", "prompt" => "", "fmt_prompt" => "",
			"order" => "", "lanage" => ""
		]);
		
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 获取画板详情
	 */
	public function getDrawInfo(Request $request) {
		$this->validate($request, [
			'drawing_id' => ['required'],
		]);

		$drawingId = $request->get('drawing_id');

		$lanage = $this->getLanage();
		$version = $this->getVersion();

		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}

		$data = [];
		$drawInfo = $this->dataOpusDrawing->getDrawInfo($drawingId);

		if($lanage == "zh") {
			$data['explain'] = $drawInfo->explain;
		} else {
			$data['explain'] = $drawInfo->en_explain;
		}

		$data['images'] = explode(',', $drawInfo->images);
		foreach($data['images'] as $key => $value) {
			$data['images'][$key] = $value."!webp";
		}
		$data['name'] = $drawInfo->name;

		$ruleData = $this->dataPay->getRuleByDrawingId($drawingId);

		$isEffective = $this->dataUserDrawing->getUserDrawIsEffective($userId, $drawingId);
		$data['expire'] = $isEffective > 0 ? $isEffective : 0;

		$userPayCount = $this->dataPay->getUserCount($userId);

		$permanent = $this->dataPay->getRuleBypermanent();
		//这里处理黄金会员是否也打8折
		if($userPayCount == 1) {
			$permanent['google_order_id'] = $permanent['google_discount_order_id'];
		}

		array_unshift($ruleData, $permanent);

		$data['rule_list'] = $ruleData;

		foreach($data['rule_list'] as $key => $item) {
			//增加参数判断当前的数据是否是打八折的数据
			$data['rule_list'][$key]['is_discount'] = $userPayCount == 1 ? true : false;
			if($userPayCount == 1) {
				$data['rule_list'][$key]['google_order_id'] = $data['rule_list'][$key]['google_discount_order_id'];
			}
		}
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 高级作画
	 */
	public function printSenior(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'],
		]);
		$realistic = $request->post('realistic') ?? null;
		$light = $request->post('light') ?? null;
		$texture = $request->post('texture') ?? null;
		$color = $request->post('color') ?? null;
		$artist = $request->post('artist') ?? null;
		$image = null;
		$prompt = $request->post('prompt');

		$taskId = $this->getRoundToken();
		$userId = $this->getTokenUser() ?? 0;

		$curUser = $this->dataUser->getUser($userId);
		$dot = 0;
		if($curUser['vip_surplus'] == 0) {
			$dot = config("app.opus_dot");

			// 老弹窗
			if($curUser['dot'] < $dot) {
				return $this->buildReturn(Code::NEET_BUY_VIP);
			}
		}

		if(!$this->dataOpus->getPaintCountOfDay($userId)) {
			return $this->buildReturn(Code::NOT_PAINT_NUM);
		}

		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}

		$tPrompt = $this->dataOpus->getCacheTranslator($prompt);
		$tPrompt = $tPrompt ?? ((new Translator())->azure($this->handleSensitiveWord($prompt)));
		$tPrompt = $this->handleSensitiveWord($tPrompt);
		$this->dataOpus->setCacheTranslator($prompt, $tPrompt);

		if($curUser['vip_surplus'] == 0) {
			//扣除1次当天剩余次数，扣除点数
			// $this->dataUser->setRemainCount($userId);
			$this->dataUser->updateDot($userId, $dot * -1, 1);
		}

		//增加一次用户每日作画次数
		// $this->dataOpus->setPaintCountOfDay($userId);

		if($realistic) {
			$tPrompt = $tPrompt.' | '.$realistic;
			$prompt = $tPrompt.' | '.$realistic;
		}
		if($light) {
			$tPrompt = $tPrompt.' | '.$light;
			$prompt = $tPrompt.' | '.$light;
		}
		if($texture) {
			$tPrompt = $tPrompt.' | '.$texture;
			$prompt = $tPrompt.' | '.$texture;
		}
		if($color) {
			$tPrompt = $tPrompt.' | '.$color;
			$prompt = $tPrompt.' | '.$color;
		}
		if($artist) {
			$tPrompt = $tPrompt.' | '.$artist;
			$prompt = $tPrompt.' | '.$artist;
		}
		if(!$image) {
			$image = '';
		}

		$data = $this->dataOpus->addPrint($prompt, $tPrompt, $taskId, $userId, $image, 1, '', '', 768, 512, $dot);

		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 通过风格作画
	 */
	public function printStyle(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'],
		]);
		$prompt = $request->post('prompt');
		$styleId = $request->post('style_id');
		$taskId = $this->getRoundToken();
		$userId = $this->getTokenUser() ?? 0;
		$resolution = $request->post('resolution');

		//判断是否是会员
		$curUser = $this->dataUser->getUser($userId);
		$dot = 0;
		if($curUser['vip_surplus'] == 0) {
			$dot = config("app.opus_dot");
			// 老弹窗
			if($curUser['dot'] < $dot) {
				return $this->buildReturn(Code::NEET_BUY_VIP);
			}
		}

		if(!$this->dataOpus->getPaintCountOfDay($userId)) {
			return $this->buildReturn(Code::NOT_PAINT_NUM);
		}

		if($this->dataOpus->getUserLen($userId) > 0) {
			return $this->buildReturn(Code::WAIT_TIME1);
		}

		$_sUserKey = !empty($userId) ? $userId : $this->getDeviceId();
		if(!$this->dataOpus->checkIntervalTime($_sUserKey)) {
			return $this->buildReturn(Code::WAIT_TIME);
		}


		$tPrompt = $this->dataOpus->getCacheTranslator($prompt);
		$tPrompt = $tPrompt ?? ((new Translator())->azure($this->handleSensitiveWord($prompt)));
		$tPrompt = $this->handleSensitiveWord($tPrompt);
		$this->dataOpus->setCacheTranslator($prompt, $tPrompt);

		$styleData = $this->dataOpus->getStyle($styleId);
		if(!$styleData) {
			$styleData = [
				'fmt_prompt' => "%s"
			];
		}

		//扣除1次当天剩余次数，扣除点数
		if($curUser['vip_surplus'] == 0) {
			// $this->dataUser->setRemainCount($userId);
			$this->dataUser->updateDot($userId, $dot * -1, 2);
		}

		//增加1次每日作画次数
		// $this->dataOpus->setPaintCountOfDay($userId);

		//竖图
		if($resolution == 1) {
			$width = 512;
			$height = 768;
		} else if($resolution == 2) {
			//正方形
			$width = 768;
			$height = 768;
		} else if($resolution == 3) {
			$width = 768;
			$height = 512;
		} else {
			$width = 512;
			$height = 768;
		}

		$tPrompt = sprintf($styleData['fmt_prompt'], $tPrompt);
		$prompt = sprintf($styleData['fmt_prompt'], $prompt);

		$data = $this->dataOpus->addPrint($prompt, $tPrompt, $taskId, $userId, '', 1, '', '', $height, $width, $dot);

		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 获取所有风格接口
	 */
	public function getStyles(Request $request) {
		$lanage = $this->getLanage();
		$data = $this->dataOpus->getStyles($lanage);
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 获取作画任务
	 */
	public function task(Request $request) {
		$this->validate($request, [
			'task_id' => ['required'],
		]);
		$taskId = $request->post('task_id');

		$data = $this->dataOpus->getTask($taskId);

		$data['is_pay'] = $this->dataPay->getIsPay($this->getTokenUser(), $this->getDeviceId());

		$data['over_times_alert'] = $this->getIsOverTimes($data['type'] ?? 1);

		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 获取我的作品列表
	 */
	public function getSelfList(Request $request) {
		$this->validate($request, [
			'index' => ['required'], 'len' => ['required'],
		]);
		$index = $request->get('index');
		$len = $request->get('len');
		$userId = $this->getTokenUser();
		$deviceId = $this->getDeviceId();
		/*if (!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}*/

		$data = $this->dataOpus->getUser($userId, $deviceId, $index, $len);
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 获取推荐作画
	 * ios 1.8.0 用于点数轮播
	 */
	public function getTopList(Request $request) {
		$this->validate($request, [
			'index' => ['required'], 'len' => ['required'],
		]);

		$index = $request->get('index');
		$len = $request->get('len');

		$lanage = $this->getLanage();
		$lanage = $lanage == 'zh' ? 'zh' : 'en';

		$sPlatform = $this->getPlatform();
		$sVersion = $this->getVersion();// >= 1.8.0
		//if(1 == $sPlatform && version_compare($sVersion, "1.7.4") > 0) {
		if(1 == $sPlatform) {
			$_aData = [
				[
					'url' => 'https://overseas-files.dalleai.art/buy_dot_top/1.png'
				], [
					'url' => 'https://overseas-files.dalleai.art/buy_dot_top/2.png'
				], [
					'url' => 'https://overseas-files.dalleai.art/buy_dot_top/5.png'
				],
			];

			$aDataList = $this->dataOpus->getTop(0, 3, $lanage, 'id', 'desc');
			//$aData = (array)$aData[0];
			$_iKey = 0;
			$data = [];
			foreach($aDataList as &$aData) {
				$aData = (array)$aData;
				$__aData = $_aData[$_iKey];
				$aData['thumb_url'] = $__aData['url'].'!thumbnail';
				$aData['down_url'] = $__aData['url']."!apple_down";
				$aData['url'] = $__aData['url'].'!webp';
				$_iKey++;

				$data[] = $aData;
			}
			//$data = $aDataList;
			Log::info("getTopList-ios", [
				'sVersion' => $sVersion, 'lanage' => $lanage, 'data' => $data, 'aDataList' => $aDataList
			]);
			unset($aDataList);
		} else {
			//$data = $this->dataOpus->getTop($index, $len, $lanage);
			if(version_compare($sVersion, '1.8.2') >= 0) {
				$data = $this->dataOpus->getTop(0, 4, $lanage, 'id', 'desc');
			} else {
				$data = $this->dataOpus->getTop(0, 1, $lanage, 'id', 'asc');
			}
		}
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	
	public function getNewTopList(Request $request) {

		$data['url'] = "https://overseas-files.dalleai.art/init/Chinoiserie_2.mp4";
		
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 获取样例列表
	 */
	public function getExampleList(Request $request) {
		$this->validate($request, [
			'index' => ['required'], 'len' => ['required'],
		]);
		$index = $request->get('index');
		$len = $request->get('len');

		$lanage = $this->getLanage();

		$data = $this->dataOpus->getExample($index, $len, $lanage);
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 最新列表
	 */
	public function getNewList(Request $request) {
		$this->validate($request, [
			'index' => ['required'], 'len' => ['required'],
		]);
		$index = $request->get('index');
		$len = $request->get('len');

		$lanage = $this->getLanage();

		$data = $this->dataOpus->getNew($index, $len, $lanage);
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 设置作品名称
	 */
	public function setTitle(Request $request) {
		$this->validate($request, [
			'title' => ['required'],
		]);
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$title = $request->get('title');
		$taskId = $request->get('task_id');

		$shumei = new Shumei();
		$title = $shumei->check($title);

		$this->dataOpus->setTitle($taskId, $title, $userId);
		return $this->buildReturn(Code::SUCCESS);
	}


	public function setTitlex(Request $request) {
		$this->validate($request, [
			'title' => ['required'], 'id' => ['required'],
		]);
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$id = $request->get('id');
		$title = $request->get('title');
		$this->dataOpus->setTitlex($id, $title, $userId);
		return $this->buildReturn(Code::SUCCESS);
	}

	/**
	 * 删除作品
	 */
	public function del(Request $request) {
		$this->validate($request, [
			'id' => ['required'],
		]);
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$id = $request->get('id');
		$info = $this->dataOpus->get($id);
		if($info["user_id"] == $userId) {
			$this->dataOpus->del($id, $userId);
			$path = str_replace(env('APP_FILES_URL').'/', '', $info["url"]);
			(new Oss())->deleteObject($path);
		}
		return $this->buildReturn(Code::SUCCESS);
	}


	/**
	 * 通过任务删除作品
	 */
	public function delTask(Request $request) {
		$this->validate($request, [
			'task_id' => ['required'],
		]);
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$taskId = $request->get('task_id');
		$this->dataOpus->delWithTaskId($taskId, $userId);
		return $this->buildReturn(Code::SUCCESS);
	}

	/**
	 * 查看提示词
	 */
	public function read(Request $request) {
		$this->validate($request, [
			'opus_id' => ['required']
		]);
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$opusId = $request->get('opus_id');

		$opusData = $this->dataOpus->get($opusId);

		$readData = $this->dataOpus->getRead($userId, $opusId);
		if($readData) {
			return $this->buildReturn(Code::SUCCESS, $opusData);
		}

		$userData = $this->dataUser->getUser($userId);
		$dot = $opusData['dot'];
		if($userData['dot'] < $dot) {
			return $this->buildReturn(Code::LACK_DOT);
		}
		DB::beginTransaction();
		$this->dataUser->updateDot($userId, -$dot, 3);
		$this->dataOpus->insertRead($userId, $opusId, $dot);
		DB::commit();
		return $this->buildReturn(Code::SUCCESS, $opusData);
	}


	/**
	 * 是否购买
	 */
	public function isBuy(Request $request) {
		$this->validate($request, [
			'opus_id' => ['required']
		]);
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$opusId = $request->get('opus_id');
		$readData = $this->dataOpus->getRead($userId, $opusId);
		if(!$readData) {
			return $this->buildReturn(Code::SUCCESS, ['is_buy' => 0]);
		}
		return $this->buildReturn(Code::SUCCESS, ['is_buy' => 1]);
	}


	/**
	 * 已经购买词条
	 */
	public function getBuyList(Request $request) {
		$this->validate($request, [
			'index' => ['required'], 'len' => ['required'],
		]);
		$index = $request->get('index');
		$len = $request->get('len');

		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}
		$data = $this->dataOpus->getBuyList($userId, $index, $len);
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	public function search(Request $request) {
		$this->validate($request, [
			'keyword' => ['required'], 'index' => ['required'], 'len' => ['required'],
		]);
		$keyword = $request->get('keyword');
		$index = $request->get('index');
		$len = $request->get('len');

		$data = $this->dataOpus->search($keyword, $len, $index);
		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 获取作品详情
	 */
	public function getOpusDetail(Request $request) {
		$this->validate($request, [
			'id' => ['required'],
		]);
		$id = $request->get('id');
		$header = $request->header();
		$data = $this->dataOpus->getDetail($id);

		$data['is_pay'] = $this->dataPay->getIsPay($this->getTokenUser(), $this->getDeviceId());
		$data['over_times_alert'] = $this->getIsOverTimes($data['type'] ?? 1);

		return $this->buildReturn(Code::SUCCESS, $data);
	}

	/**
	 * 获取是否还有使用次数
	 */
	public function getIsOverTimes($type){
		$over_times_alert = false;
		$userId = $this->getTokenUser();
		$deviceId = $this->getDeviceId();
		$isVip = 0;
		if ($userId <= 0) {
			$times = (new Opus())->getCountByWhere(["device_id" => $deviceId,"type" => $type]);
		}else{
			$uinfo = $this->dataUser->getUser($userId);
			if ($uinfo) {
				if (time() <= $uinfo['vip_exp'] || 1 == $uinfo['is_super_vip']) {//会员
					$isVip = 1;
				}else{
					$times = (new Opus())->getCountByWhere(["user_id" => $userId,"type" => $type]);
				}
			}else{
				$times = (new Opus())->getCountByWhere(["device_id" => $deviceId,"type" => $type]);
			}
		}
		if (0 == $isVip && $times >= FunTool::getFreeNum()) {
			$over_times_alert = true;
		}
		return $over_times_alert;
	}

	/**
	 * @desc 投稿作品
	 */
	public function contribution(Request $request) {
		$this->validate($request, [
			'id' => ['required'],
		]);
		$id = $request->post('id');

		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}

		//是否已投稿
		$opus = $this->dataOpus->getOpusDetail($userId, $id, ['contri_status']);
		if(!$opus) {
			return $this->buildReturn(Code::ERROR);
		}

		if($opus['contri_status'] != 0) {
			return $this->buildReturn(Code::NOT_REPEAT_CONTRIBUTION);
		}

		$result = $this->dataOpus->updateData($userId, $id, ['contri_status' => 1]);
		if(!$result) {
			return $this->buildReturn(Code::CONTRIBUTION_ERROR);
		}

		return $this->buildReturn(Code::SUCCESS);
	}

	public function message() {
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}

		$point = $this->dataOpus->getMessage($userId);
		return $this->buildReturn(Code::SUCCESS, ['point' => $point]);
	}

	public function examine(Request $request) {
		$this->validate($request, [
			'id' => ['required'], 'user_id' => ['required'], 'type' => ['required', Rule::in([2, 3])] // 2拒绝 3通过
		]);

		$id = $request->post('id');
		$userId = $request->post('user_id');
		$type = $request->post('type');

		$opus = $this->dataOpus->getOpusDetail($userId, $id, ['contri_status']);
		if(!$opus) {
			$this->buildReturn(Code::ERROR);
		}

		$result = $this->dataOpus->examineOpus($userId, $id, $opus, $type);
		return $this->buildReturn(Code::SUCCESS, ['res' => $result]);
	}

	public function onclick(Request $request) {
		$userId = $this->getTokenUser() ?? 0;
		if(!$userId) {
			return $this->buildReturn(Code::NOT_LOGIN);
		}

		$result = $this->dataOpus->onclick($userId);
		return $this->buildReturn(Code::SUCCESS);
	}

	public function test() {
		$this->dataOpus->test();
	}

	/**
	 * 获取画板
	 */
	public function getTab(Request $request) {
		$opusDrawing = new OpusDrawing();
		$list = $opusDrawing->getList();

		foreach($list as $key => $value) {
			$list[$key]->name = $value->en_name;
		}
		return $this->buildReturn(Code::SUCCESS, $list);
	}

	/**
	 * 检验每天做第四张非高清图片弹窗
	 */
	public function checkNoHighAlert(Request $request){

		$userId = $this->getTokenUser();

		$deviceId = $this->getDeviceId();

		$amount = $this->dataOpus->getNoHighAmountByDay($userId, $deviceId);

		$lastInfo = $this->dataOpus->getLastOpuInfo($userId, $deviceId);

		$isPay = $this->dataPay->getIsPay($userId, $deviceId);

		$alert_three_key = "ALERT-".$userId.'-'.$deviceId; 

		Log::info("alert-alert", [$amount, $alert_three_key, $request->post('type')]);

		if (1 == $this->getPlatform()) {//ios特殊逻辑兼容
			$type = $request->post('type');
			if (1 == $type) {//alert
				if (Redis::EXISTS($alert_three_key)) {
					return $this->buildReturn(Code::SUCCESS, ['alert'=>false, 'is_pay'=>$isPay, 'is_high'=>false]); 
				}else{
					if ($amount == 3 && 1 == $lastInfo['is_high']) {
						$tomorrow = date('Y-m-d', strtotime("+1 day"));
						$ttl = strtotime($tomorrow) - time();
						Redis::SET($alert_three_key, 1);
						Redis::EXPIRE($alert_three_key, $ttl);
						return $this->buildReturn(Code::SUCCESS, ['alert'=>true,'is_pay'=>$isPay,'is_high'=>false]); 
					}else{
						return $this->buildReturn(Code::SUCCESS, ['alert'=>false,'is_pay'=>$isPay,'is_high'=>false]); 
					}
				}

			}
			if (2 == $type) {//is_high
				if ($amount == 3) {
					return $this->buildReturn(Code::SUCCESS, ['alert'=>false,'is_pay'=>$isPay,'is_high'=>true]); 
				}else{
					return $this->buildReturn(Code::SUCCESS, ['alert'=>false,'is_pay'=>$isPay,'is_high'=>false]); 
				}
			}
			
		}else{
			if (Redis::EXISTS($alert_three_key)) {
				return $this->buildReturn(Code::SUCCESS, ['alert'=>false, 'is_pay'=>$isPay]); 
			}else{
				if ($amount >= 3) {
					$tomorrow = date('Y-m-d', strtotime("+1 day"));
					$ttl = strtotime($tomorrow) - time();
					Redis::SET($alert_three_key, 1);
					Redis::EXPIRE($alert_three_key, $ttl);
					return $this->buildReturn(Code::SUCCESS, ['alert'=>true,'is_pay'=>$isPay]); 
				}else{
					return $this->buildReturn(Code::SUCCESS, ['alert'=>false,'is_pay'=>$isPay]); 
				}
			}
		}

		

	}


	//敏感词替换 start
	public function handleSensitiveWord($sPrompt, $sReplacement = '***') {

		$string = Sensitive::formatData($sPrompt, $sReplacement, $this->getTokenUser(), $this->getPlatform());

        return $string;
	}

	private function _replaceSensitiveWord($sString, $aSensitiveWord, $sReplacement = '***') {
		$bIsEn = $this->_isEn($sString);
		foreach($aSensitiveWord as $sSensitiveWord) {
			if(true === $bIsEn) {
				if(strtolower($sString) == $sSensitiveWord) {
					return $sReplacement;
				}
			} else {
				$sString = str_ireplace($sSensitiveWord, $sReplacement, $sString);
			}
		}
		return $sString;
	}

	private function _isEn($sKeyword) {
		$Res = preg_match('/^[A-Za-z0-9]+$/', $sKeyword);
		if($Res) {
			return true;
		} else {
			return false;
		}
	}
	//敏感词替换 end


	/**
	 * 文生视频回调
	 */
	public function createVideoCallback(Request $request) {
		$this->validate($request, [
			'taskId' => ['required'],
			'status' => ['required']
		]);
		$taskId = $request->get('taskId');
		$data = $request->post();
		return $this->buildReturn(Code::SUCCESS, $data);
	}


	/**
	 * 文生视频生成
	 */
	public function createVideo(Request $request) {
		$this->validate($request, [
			'motion' => ['required'],
			'prompt' => ['required'],
			'proportion' => ['required'],
			'videoDuration' => ['required'],
			'videoQuantity' => ['required']
		]);
		$motion = $request->get('motion');
		$prompt  = $request->get('prompt');
		$proportion = $request->get('proportion');
		$videoDuration = $request->get('videoDuration');
		$videoQuantity = $request->get('videoQuantity');
		$result = $this->dataMuseFrameLib->addTask($motion, $prompt, $proportion, $videoDuration, $videoQuantity);
		//motion、prompt、proportion、videoDuration、videoQuantity
		$data = $request->post();
		$data['result'] = $result;
		return $this->buildReturn(Code::SUCCESS, $data);
	}

}
